DDSキットをコントロールする専用Windowsソフトを作ってみよう!



<項目>シリアルポートの制御方法の選択
Visual Basicで、シリアルポートを制御する場合、次の2つの方法が一般的に知られています。
(1)通信制御用APIを使う
Visual BasicからWindowsのOSに含まれているAPI(Application Program Interface)関数を呼び出して制御します。
(2)通信制御用ActiveXを使う
Visual Basic4.0以降から標準で組み込まれた機能で、OCXコントロールの形式で提供されているため、フォームに貼り付けるだけでシリアル通信機能が使えるようになります。

ここでは、フォームに貼り付けるだけでシリアル通信機能が使えるということで、(2)の通信制御用ActiveXを使うことにします。
詳細はこちら


<項目>画面のデザイン(フォームウインドウ)
図1に示すようなフォームウインドウを使って、プログラムの実行時に表示させたいものを配置していきます。DDSの周波数データを表示する場所として、3桁ごとに区切って表示できるように3つのテキストボックス(txtMHz,txtKHz,txtHz)を使いました。また、その下の3本のスクロールバー(hsbMHz,hsbKHz,hsbHz)ですが、これは簡単にスクロールすることで設定周波数をいちいち入力しなくとも設定できるようにしています。
またいくつかラベルを使って、設定周波数のタイトル表示や周波数単位表示も配置しました。データの送信(シリアル通信)の開始には、コマンドボタン(Command1)として、「DDS設定の実行」を配置しました。
lbl_outとあるところには、DDSの状態をメッセージ表示します。
MSCommコンポーネントを右上に貼り付けておきますが、プログラムの実行時には表示はされませんので、貼り付ける場所はフォーム内であればどこでも結構です。

図1.フォームウインドウのデザイン


図1で3本のスクロールバーを配置しています。設定の周波数帯を、MHz,kHz,Hzに分けました。DDS出力の最高周波数は約17MHzですので、txtMHzのスクロールバーのMaxプロパティは、17としておきます。その他のスクロールバーは、Maxが999になります。スクロールバーの「バー」の部分をクリックしたときの変更量は、LargeChangeプロパティで設定します。LargeChangeプロパティを設定すると、MinプロパティとMaxプロパティの値を使って、適切な大きさにスクロールボックスが調整されます。また、スクロールバーの両端の矢印ボタンをクリックしたときの変更量はSmallChangeプロパティで設定します。どちらも既定値は1です。MHzのスクロールバーでは変化幅が0〜17ですのでLargeChangeプロパティを2とし、kHzとHzのスクロールバーでは変化幅が0〜999と広いので、LargeChangeプロパティを100程度に設定しておきましょう。SmallChangeプロパティは1のままでよいでしょう。

図2.スクロールバー



<項目>プログラムの記述(フォームモジュール)
→ここをクリックして、下記のファイルをダウンロードするようにしてください。

  <ダウンロードする>ファイル名:「dds31.lzh」 サイズ61.4kバイト

ソフトはLHA形式で圧縮してあるので、解凍して使ってください。まず、解凍することで現れるフォルダの中にあるMscomm32.ocxを、Windows\Systemにコピーしてください。それから、EXEファイルを実行すれば起動します。特にインストーラーが付属しているわけではありませんので、プログラムファイルへの登録やショートカットの作成はご自分でなさってください。ソフトを削除したい場合は、そのまま削除してください。

Option Explicit
'(1)変数宣言の強制指定
Private Sub Form_Load()
    ' MSCommコントロールの初期設定
    MSComm1.CommPort = 1
    MSComm1.Settings = "9600,n,8,1"
    MSComm1.RThreshold = 1
    MSComm1.SThreshold = 1
    lblOut.Caption = ""
End Sub



'(2)通信ポートCOM1を指定
'(3)通信条件設定
'(4)1バイト受信毎にOnCommイベント発生
'   送信バッファ空でOnCommイベント発生

'(5)DDSの出力状況表示


Private Sub hsbMHz_Change()
    txtMHz.Text = hsbMHz.Value
End Sub

'(6) スクロールバーの値(MHz単位)を
'   テキストデータとして文字表示


Private Sub hsbKHz_Change()
    txtKHz.Text = Format(hsbKHz.Value, "000")
End Sub

'(7)スクロールバーの値(kHz単位)を
'   テキストデータとして3桁の文字表示


Private Sub hsbHz_Change()
    txtHz.Text = Format(hsbHz.Value, "000")
End Sub

'(8)スクロールバーの値(Hz単位)を
'   テキストデータとして3桁の文字表示


Private Sub hsbMHz_Scroll()
    txtMHz.Text = hsbMHz.Value
End Sub

'(9)ドラッグ中のスクロールバーの値(MHz単位)を
'   テキストデータとして文字表示


Private Sub hsbKHz_Scroll()
    txtKHz.Text = Format(hsbKHz.Value, "000")
End Sub

'(10)ドラッグ中のスクロールバーの値(kHz単位)を
'   テキストデータとして3桁の文字表示


Private Sub hsbHz_Scroll()
    txtHz.Text = Format(hsbHz.Value, "000")
End Sub

'(11)ドラッグ中のスクロールバーの値(Hz単位)を
'   テキストデータとして3桁の文字表示


Private Sub Command1_Click()
    Dim freq As Long
    Dim hexfreq As String
    Dim retvalue As Integer
    Dim Chip_data As String
    Dim Command_data As String
    Dim freq_data(6) As String
    Dim i As Integer
'(12)Command1のクリックイベントプロシージャ
'(13)周波数データ変数
'(14)周波数データの16進数文字表示
'(15)警告メッセージの戻り値(ダミー変数)
'(16)DDSチップセレクトデータ変数
'(17)DDSコマンドデータ変数
'(18)6分割した周波数データ
'(19)ループカウンタ変数
    If MSComm1.PortOpen = False Then
      MSComm1.PortOpen = True
    End If
'(20)シリアルポートがクローズしていたら
'   シリアルポートのオープン

    Chip_data = "7"
    Command_data = "C"
'(21)DDSチップセレクトデータ(CS2=H,CS1=H,CS0=H)で「111」
'(22)DDSコマンドデータ「C」
    freq = CDbl(txtMHz.Text) * 1000000# + CDbl(txtKHz.Text) * 1000# + CDbl(txtHz.Text) '(23)入力した周波数データ
    hexfreq = Hex(freq)
    If Len(hexfreq) > 6 Then
'(24)周波数データを16進表記に変換
'(25)DDSの設定できない周波数範囲(警告メッセージの表示)
      retvalue = MsgBox("16.777216Hz以上は設定できません!", vbOKOnly + vbCritical, "DDS周波数設定エラー")
    Else
      Do While Len(hexfreq) < 6
        hexfreq = "0" + hexfreq
      Loop

'(26)16進表記の周波数データ長を6文字に整える
'   データ長が6文字以下なら先頭に0を入れる

      For i = 1 To 6
        freq_data(i) = Mid(hexfreq, i, 1)
      Next i


'(27)周波数データを6分割

      MSComm1.Output = MakeByte(Chip_data)
      MSComm1.Output = MakeByte(Command_data)
      For i = 6 To 1 Step -1
        MSComm1.Output = MakeByte(freq_data(i))
      Next i
      lblOut = Format(freq, "#,#") & "Hzを出力中"
    End If

End Sub
'(28)チップセレクトデータの送信
'(29)コマンドデータの送信

'(30)周波数データの送信

'(31)出力の表示



Private Sub MSComm1_OnComm()
    Select Case MSComm1.CommEvent
      Case comEvReceive
'(32)送受信のOnCommイベント
'(33)CommEventプロパティに対する処理
'(34)通信イベントでは何もしない
      Case comEvSend
      Case comEvCTS
      Case comEvDSR
      Case comEvCD
      Case comEvRing
      Case comEvEOF





      Case comEventBreak
        MsgBox "中断信号を受信", vbCritical
      Case comEventCTSTO
        MsgBox "CTSタイムアウト", vbCritical
      Case comEventDSRTO
        MsgBox "DSRタイムアウト", vbCritical
      Case comEventFrame
        MsgBox "フレーム エラー", vbCritical
      Case comEventOverrun
        MsgBox "ポート オーバーラン", vbCritical
      Case comEventCDTO
        MsgBox "CDタイムアウト", vbCritical

      Case comEventRxOver
'(35)警告メッセージ アイコンを表示











        MsgBox "受信バッファ オーバーフロー", vbCritical
      Case comEventRxParity
        MsgBox "パリティ エラー", vbCritical
      Case comEventTxFull



        MsgBox "送信バッファがいっぱい", vbCritical
      Case comEventDCB
        MsgBox "予期しないDCBエラー", vbCritical
      Case Else
        MsgBox "その他の通信エラー", vbCritical
    End Select

End Sub







Private Sub Form_Unload(Cancel As Integer)
    If MSComm1.PortOpen = True Then
        MSComm1.PortOpen = False
    End If
End Sub

'(36)Unoadイベントプロシージャ

'(37)シルアルポートを閉じる



Private Function MakeByte(str As String) As String
    Dim char_code As Byte
    Select Case str
      Case "A" To "F"
        char_code = Asc(str) - 55
      Case "0" To "9"
        char_code = Asc(str) - 48
    End Select
    MakeByte = Chr(char_code)
End Function

'(38)文字データ→バイトデータに変換
'(39)0〜15までの数値データ変数
'(40)数字か英字で場合分け
'(41)A〜Fまでの文字データを
'   10〜15までの数値に変換
'(42)0〜9までの文字データを
'   0〜9までの数値に変換

'(43)数値データをバイトデータに変換




【プログラムの説明】ここがポイント
このプログラムについて、順を追って解説を加えておきましょう。

(1)変数宣言の強制指定
Visual Basicでは変数を利用する前に、変数の名前とデータ型を宣言します。しかし、宣言し忘れた変数を使ってもエラーになりません。Visual Basicでは、これまでに宣言されていない文字を見つけると、バリアント型の変数として解釈します。便利なようですが、これが落とし穴にもなりかねません。まず、タイプミスを発見できません。自分では宣言した変数を使っているつもりでも、タイプミスをしている場合があります。このとき、エラーにならずに新しい変数と解釈してしまうので、結果的に期待した通りに動いてくれません。また、バリアント型の変数は16バイトの領域を使用します。バリアント型を多用すると、使用できるメモリが少なくなることも注意しなければなりません。宣言していない変数を利用できないようにするには、Option Explicitステートメントを使います。Option Explicitステートメントは、モジュールの宣言セクションに記述してください。モジュールの宣言セクションとは、コードウインドウで「オブジェクト」ボックスに"(General)",「プロシージャ」ボックスに"(Declarations)"が表示されている状態です。

(2)MSCommコントロールの初期設定,通信ポートの指定
CommPort プロパティを使用して、どのシリアル ポートを開くかを指定します。この例では、通信機器が COM1 ポートに接続されているものとして、プロパティの値を 1 (COM1) に設定しています。CommPort プロパティの既定値は 1 で、1 〜 16 の範囲の任意の数値を設定できます。ただし、アプリケーションが動作するシステムに存在しない COM ポート番号を指定すると、エラーが発生します。

(3)通信条件設定
Settings プロパティを使用して、通信速度、パリティ、データ長、およびストップビットを指定します。指定フォーマットは "BBBB,P,D,S" です。ここで BBBB は通信速度 (bps)、P はパリティ、D はデータ長、S はストップ ビット長です。特に指定しない限り、通信速度は 9600bps に設定されます。パリティは、データの伝送エラーをチェックするために設定します。通常、パリティは使用しないので "N" に設定します。データ長では、何ビットで 1 バイト分のデータを表すかを指定します。ストップビットは、データの受信を 1 バイト分ごとに同期をとって行うために使用されます。(詳細はこちら 表2 Settings プロパティを参照

(4)1バイト受信毎にOnCommイベント発生
MSCommコントロールの送受信のOnCommイベントを発生させるためには、送信はバッファが空になった時に、受信は、毎回のデータの受信ごとに発生するように、スレッショルドを1にセットしておきます。

(5)DDSの出力状況表示
テキストボックスの表示文字の初期設定では、表示なしに設定

(6)スクロールバーの値(MHz単位)をテキストデータとして文字表示
実行時にスクロールボックスを動かすと、Changeイベントが発生します。スクロールバーの値を変更したときに実行するプログラムは、Changeイベントプロシージャに作成します。ここでは、オブジェクト名「hsbMHz」のスクロールバーの値(MHz単位)が変更されたときに、オブジェクト名「txtMHz」のテキストボックスに新しいValue値を文字表示しています。

(7)スクロールバーの値(kHz単位)をテキストデータとして3桁の文字表示
ここでは、オブジェクト名「hsbKHz」のスクロールバーの値(kHz単位)が変更されたときに、オブジェクト名「txtKHz」のテキストボックスに新しいValue値を文字表示しています。ただし、ここでは数値の桁数を3桁に揃える必要がありますので、Format関数を使っています。引数として”000”を使って、0で埋める3桁指定となっています。

(8)スクロールバーの値(Hz単位)をテキストデータとして3桁の文字表示
ここでは、オブジェクト名「hsbHz」のスクロールバーの値(Hz単位)が変更されたときに、オブジェクト名「txtHz」のテキストボックスに新しいValue値を文字表示しています。ただし、ここでは数値の桁数を3桁に揃える必要がありますので、Format関数を使っています。引数として”000”を使って、0で埋める3桁指定となっています。

(9)ドラッグ中のスクロールバーの値(MHz単位)をテキストデータとして文字表示
スクロールボックスを移動している間は、Scrollイベントが発生します。このときにValueプロパティの値を参照すると、ドラッグ中の値を取得することができます。Scrollイベントはスクロールバーをクリックしたときや、スクロールバーの両側の矢印ボタンをクリックした時には発生しないので注意してください。ここでは、オブジェクト名「hsbMHz」のスクロール中の値(MHz単位)を、オブジェクト名「txtMHz」のテキストボックスに新しいValue値として文字表示しています。

(10)ドラッグ中のスクロールバーの値(kHz単位)をテキストデータとして3桁の文字表示
ここでは、オブジェクト名「hsbKHz」のスクロール中の値(kHz単位)を、オブジェクト名「txtKHz」のテキストボックスに新しいValue値として文字表示しています。ただし、ここでは数値の桁数を3桁に揃える必要がありますので、Format関数を使っています。引数として”000”を使って、0で埋める3桁指定となっています。

(11)ドラッグ中のスクロールバーの値(Hz単位)をテキストデータとして3桁の文字表示
ここでは、オブジェクト名「hsbHz」のスクロール中の値(Hz単位)を、オブジェクト名「txtHz」のテキストボックスに新しいValue値として文字表示しています。ただし、ここでは数値の桁数を3桁に揃える必要がありますので、Format関数を使っています。引数として”000”を使って、0で埋める3桁指定となっています。

(12)Command1のクリックイベントプロシージャ
マウスで「Command1」のオブジェクトをポイントした後、マウスボタンを押して離したときに発生します。

(13)周波数データ変数
DDSの設定周波数データの変数を、長整数型で変数宣言しておきます。

(14)周波数データの16進数文字表示
設定周波数データの16進文字表示の変数を、文字型で変数宣言しておきます。

(15)警告メッセージの戻り値(ダミー変数)
メッセージボックス(MsgBox関数)の戻り値を、整数型で変数宣言しておきます。ここでは、MsgBox関数の戻り値を一時的に入れて置く、ダミー的な変数として使っています。

(16)DDSチップセレクトデータ変数
DDSのチップセレクトデータを、文字型で変数宣言しておきます。

(17)DDSコマンドデータ変数
DDSのコマンドデータを、文字型で変数宣言しておきます。

(18)6分割した周波数データ
DDSの下位24ビット分の周波数データですが、下位から4ビットずつ区切って6分割し、文字型の配列変数へ格納するようにします。

(19)ループカウンタ変数
for〜Nextステートメントのカウンタ変数を、整数型で変数宣言しておきます。

(20)シリアルポートがクローズしていたらシリアルポートのオープン
PortOpen プロパティを使って接続を確立します。PortOpen プロパティの値はブール型で、真 (True) または偽 (False) となります。PortOpen プロパティの値がFalseでクローズされているときには、Trueにしてオープンします。
なお、ポートに異常がある場合や、CommPort プロパティの設定値が正しくない場合、または使用するシリアル デバイスが、指定されたパラメータ値をサポートしていない場合は、エラーが発生したり、外部デバイスが正常に動作しないことがあります。

(21)DDSチップセレクトデータ(CS2=H,CS1=H,CS0=H)で「111」
DDSのチップセレクトデータですが、CS2=H,CS1=H,CS0=Hで「111」となります。文字変数で”7”を代入します。

(22)DDSコマンドデータ「C」
DDSのコマンドデータですが、ここではコマンド「C」を使いました。コマンド「C」とは、DDSのメモリ1CHに26ビットの周波数データを書き込みこれを出力するものです。→詳細はこちら

(23)入力した周波数データ
freq = CDbl(txtMHz.Text) * 1000000# + CDbl(txtKHz.Text) * 1000# + CDbl(txtHz.Text)
入力された周波数データは、テキストボックスにMHz単位,kHz単位,Hz単位でそれぞれ入力されています。したがって、txtMHz.Textでは 1000000#倍し、txtKHz.Textでは 1000#倍してそれぞれ足しています。ここでシャープ記号 (#)は、倍精度浮動小数点型の型宣言文字を示しています。また、テキストボックスに入力された値は文字型ですので、型変換関数CDbl( )で、文字データ型を倍精度浮動小数点型へ変換しています。ここで、Visual Basicでは以前のバージョンほどデータ型に厳しくはなく、
freq = txtMHz.Text * 1000000# + txtKHz.Text * 1000# + txtHz.Text のように
型変換関数を使わずに、文字型変数を倍精度浮動小数点型変数に直接代入してもエラーにはなりません。
ただし、ほかのプログラミング言語の中には、とても厳しくチェックするものもありますので、データ型は常に意識する習慣を付けておく方がよいでしょう。

(24)周波数データを16進表記に変換
周波数データを 16 進数で表した文字列型 (String)に変換 します。
例) 1,000,000 → F4240

(25)DDSの設定できない周波数範囲(警告メッセージの表示)
DDSの設定できない周波数範囲ですが、周波数データを 16 進数で表したときに「FFFFFF」までとなります。すなわち、
16,777,215以上は設定できません。 MsgBox関数を使うと、「はい」ボタンや「いいえ」ボタンを含んだメッセージボックスを表示することができます。MsgBox関数はユーザーが選択したボタンの種類を返しますので、ボタンに応じて細かく処理を分岐することができます。構文とその内容は以下のようになっています。

retvalue = MsgBox ( prompt, buttons, title, helpfile, context )
retvalue :戻り値 ユーザーが選択したボタンを表す整数型の値を返す
       [OK]ボタン :1 vbOK
       [キャンセル]ボタン :2 vbCancel
       [中止]ボタン :3 vbAbort
       [再試行]ボタン :4 vbRetry
       [無視]ボタン :5 vblgnore
       [はい]ボタン :6 vbYes
       [いいえ]ボタン :7 vbNo
prompt   :メッセージボックスに表示する文字列
buttons :メッセージボックスに含むボタンとアイコンの種類
 以下の定数の合計値で指定(省略可能)
    ボタンの種類
       定数 意味
       vbOKOnly [OK]
       vbOKCancel [OK],[キャンセル]
       vbAbortRetryIgnore [中止],[再試行],[無視]
       vbYesNoCancel [はい],[いいえ],[キャンセル]
       vbYesNo [はい],[いいえ]
       vbRetryCancel [再試行],[キャンセル]
    アイコンの種類
          定数 意味
          vbCritical 16 警告[×]
          vbQuestion 32 問い合わせ[?]
          vbExclamation 48 注意[!]
          vbInformation 64 情報[!]
    デフォルトボタン
          定数 意味
          vbDefaultButton1 第1ボタン
          vbDefaultButton2 256 第2ボタン
          vbDefaultButton3 512 第3ボタン
          vbDefaultButton4 768 第4ボタン
title :メッセージボックスのタイトルバーに表示する文字列(省略可能)
helpfile :ヘルプファイルの名前(省略可能)
context :ヘルプトピックに指定したコンテキスト番号(省略可能)

ここのプログラムでは、
prompt:メッセージボックスに表示する文字列が、"16.777216Hz以上は設定できません!"と表示して、
buttons:メッセージボックスに含むボタンとアイコンの種類が、 vbOKOnly + vbCritical なので、
      ボタンの種類が[OK]、アイコンの種類が、警告[×]になります。
title:メッセージボックスのタイトルバーに表示する文字列が、"DDS周波数設定エラー"となっています。

(26)16進表記の周波数データ長を6文字に整える。データ長が6文字以下なら先頭に0を入れる
周波数データを 16 進数で表した文字変数のデータ長を6文字にします。データ長が6文字に満たない場合には先頭に0を入れて6文字にします。
例) F4240 → 0F4240

(27)周波数データを6分割
DDSの下位24ビット分の周波数データですが、下位から4ビットずつ区切って6分割し、文字型の配列変数へ格納するようにします。Mid関数により、文字データ(hexfreq変数)の先頭から 1文字ずつ取得します。

例) 0F4240の場合
   周波数データ(1): 20ビット目〜23ビット目  0
   周波数データ(2): 16ビット目〜19ビット目  F
   周波数データ(3): 12ビット目〜15ビット目  4
   周波数データ(4):  8ビット目〜11ビット目  2
   周波数データ(5):  4ビット目〜 7ビット目  4
   周波数データ(6):  0ビット目〜 3ビット目  0

(28)チップセレクトデータの送信
DDSの設定データは、まずチップセレクトデータから送信します。データの送信は、MSComm1.Outputにデータを入れていきます。MakeByte( )プロシージャは文字データをバイトデータに変換します。

(29)コマンドデータの送信
引き続いて、DDSのコマンドデータを送信します。

(30)周波数データの送信
引き続いて、DDSの周波数データを送信します。ただし、6分割した周波数データは下位から順に送信するようにします。

(31)出力の表示
確認のため、lblOutのラベルに出力周波数の表示をさせます。
Format(freq, "#,#") & "Hzを出力中"とありますが、Format関数により3桁ごとに数字を区切って表示します。
例)1MHzの場合は、 「1,000,000Hzを出力中」 と表示されます。

(32)送受信のOnCommイベント
MSCommコントロールの送受信のOnCommイベントは、送信はバッファが空になった時に、受信は、毎回のデータの受信ごとに発生するようにしてあります。また、通信エラーになっても、OnComm イベントが発生します。

(33)CommEventプロパティに対する処理
CommEvent プロパティを参照すると、OnComm イベントが発生する原因になった具体的なエラーまたはイベントを調べることができます。

(34)通信イベントでは何もしない
CommEvent プロパティを参照すると、OnComm イベントが発生する原因になった他のイベントを調べることができます。通信イベントの発生では、特に何もしません。(詳細は、 CommEvent プロパティの通信イベント定数を参照)

(35)警告メッセージ アイコンを表示
CommEvent プロパティを参照すると、OnComm イベントが発生する原因になった通信エラーを調べることができます。通信エラーの発生では、メッセージを表示するようにします。(詳細は、 CommEvent プロパティの通信エラー定数を参照

(36)Unoadイベントプロシージャ
フォームが画面から消去 (アンロード) されるときに発生します。

(37)シルアルポートを閉じる
シリアル ポートは、PortOpen プロパティを使って接続を解除できます。

(38)文字データ→バイトデータに変換
送信データですが、MakeByte( )プロシージャにより、16進文字データをバイトデータに変換します。

(39)0〜15までの数値データ変数
”0”〜”F”の16進文字データを、0〜15までの数値データに変換した値を格納するデータ変数

(40)数字か英字で場合分け
”0”〜”F”の16進文字データを、”0”〜”9”か、”A”〜”F”かで処理を場合分けする。

(41)A〜Fまでの文字データを、10〜15までの数値に変換
”A”のAsciiコードは 65なので、55を引けば 10となります。
”B”のAsciiコードは 66なので、55を引けば 11となります。
  ・・・・・
”F”のAsciiコードは 70なので、55を引けば 15となります。

(42)0〜9までの文字データを、0〜9までの数値に変換
”0”のAsciiコードは 48なので、48を引けば 0となります。
”1”のAsciiコードは 49なので、48を引けば 1となります。
  ・・・・・
”9”のAsciiコードは 57なので、48を引けば 9となります。

(43)数値データをバイトデータに変換
chr関数により、数値データをバイトデータに変換し、この値をMakeByteの戻り値とします。


<項目>DDS制御プログラム(3)
リセット後、PICが動作していることを簡単に確認するため、PORTBに接続されたLEDが1秒間点灯します。DSSの設定ですが、 パソコンから次の8つの設定データをRS232Cでシリアル送信します。

  1. チップセレクトデータ
  2. コマンドデータ
  3. 周波数データ(0ビット目〜3ビット目)
  4. 周波数データ(4ビット目〜7ビット目)
  5. 周波数データ(8ビット目〜11ビット目)
  6. 周波数データ(12ビット目〜15ビット目)
  7. 周波数データ(16ビット目〜19ビット目)
  8. 周波数データ(20ビット目〜23ビット目)

周波数データは、次のように6つに分割して送ります。
シリアル送信されたデータはPIC側で一度バッファに格納された後、DDSへ設定データを送ります。なお、設定完了後も受信動作を続けますので、パソコン側で各種コマンドや周波数を新たに設定することも可能です。

→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
  <ダウンロードする>ファイル名:「dds_3.asm」 サイズ7.81kバイト

→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
  <ダウンロードする>ファイル名:「dds_3.hex」 サイズ717バイト

;***********************************************************
; DDSコントロール・プログラム3

;【 動作内容 】
;  PICリセット後、確認のため PORTB の LED が1秒間点灯する。
;  パソコンからのデータは、
;  チップセレクトデータ(3ビット)
;  コマンドデータ(4ビット)及び
;  周波数データ(24ビット)
;  を、RS232C シリアル通信で送る。
;  周波数データは、下位から4ビットずつ区切って6分割し、
;  下位から順に、分割したデータとして送る。
;  各データはバッファに一時格納し、データの受信が完了したら、
;  随時、DDS 設定信号を出力する。
;
;【 DDS 接続ポート 】
; (DDS) (PIC)
; STB ………RE0
; DATA………RE1
; SCK ………RE2
;
;【 RS-232C 接続ポート 】
; 非同期式通信モード
; ボーレート 9600bps
; 8ビット・ノンパリティ
; 割り込みは使用しない
;
;***********************************************************
    LIST   P=PIC16F877
    INCLUDE  P16F877.INC
;(1)プロセッサの種別指定
;(2)インクルードファイルの指定
;***********************************************************
; 変数定義とレジスタ割付
;***********************************************************
COUNT   EQU  20H
COUNT1  EQU  21H
COUNT2  EQU  22H
COUNT3  EQU  23H
COUNT4  EQU  24H

TEMP    EQU  25H
COUNT_D  EQU  26H
COUNT_S  EQU  27H

;(3)ループカウンタ
;   ループカウンタ1
;   ループカウンタ2
;   ループカウンタ3
;   ループカウンタ4

;   一時保管データ
;   データカウンタ
;   シフトカウンタ

;***********************************************************
; 初期化
; (注)バンクの位置に注意
;***********************************************************
    ORG   0
    BSF   STATUS,RP0
    MOVLW  B'00000010'
    MOVWF  ADCON1
    CLRF  TRISE
    CLRF  TRISB
    MOVLW  B'10111111'
    MOVWF  TRISC
    MOVLW  B'00100100'
    MOVWF  TXSTA
    MOVLW  81H
    MOVWF  SPBRG
    BCF   STATUS,RP0
    MOVLW  B'10010000'
    MOVWF  RCSTA

;(4)プログラムの開始番地の指定
;(5)Bank 1 へ切替
;(6)RE0,RE1,RE2 デジタル入出力
;   ADCON1レジスタの設定
;(7)PORTE 全ポートを出力に設定
;(8)PORTB 全ポートを出力に設定
;(9)RC7/RX(入力),RC6/TX(出力)
;(10)PORTC の設定
;(11)8BIT,送信許可,非同期,高速
;   TXSTA レジスタの設定
;(12)ボーレート 9600bps (20MHz:高速設定時)
;   SPBRG レジスタの設定
;(13)Bank 0 へ戻す
;(14)シリアル,8BIT,継続受信許可
;   RCSTA レジスタの設定

;***********************************************************
; メインプログラム
;***********************************************************

    MOVLW  B'00000111'
    MOVWF  PORTE
MAIN
    BSF   STATUS,IRP
    MOVLW  0A0H
    MOVWF  FSR
    
MOVLW  8H
    MOVWF  COUNT_D

;(15)DDS信号ラインのレベルの初期設定
;   SCK,DATA,STB = [H],[H],[H] に設定
;   PORTEへ出力(DDSとの通信の初期設定)

;(16)間接アドレス設定
;   バッファの先頭アドレスをセットする
;   間接アドレスポインタの初期化
;(17)8回繰り返す(DDS設定データ)
;   データカウンタのセット


    MOVLW  B'11111111'
    MOVWF  PORTB
    CALL  TIME1S
    MOVLW  B'00000000'
    MOVWF  PORTB

;(18)データ受信待ちになっていることを確認するためのLED表示
;   11111111 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの点灯)
;(19)1秒のウエイトを入れる
;(20)00000000 を Wreg にロードする
;    PORTBへWregのデータを出力(LEDの消灯)


LPRCV
    BTFSS  PIR1,RCIF
    GOTO  LPRCV




;(21)USART 受信割り込みフラグビットのチェック
;   PIR1 レジスタの RCIF が「0」だったら
;   LPRCV ラベル間をループする


    BTFSC  RCSTA,FERR
    GOTO  FRAME

    BTFSC  RCSTA,OERR
    GOTO  OVER

; ****** エラーチェック ******
;(22)フレーミングエラーのチェック(1:エラー,0:正常)
;   フレーミングエラー時 FRAME のラベルへジャンプする
;
;(23)オーバーランエラーのチェック(1:エラー,0:正常)
;   オーバーランエラー時 OVER のラベルへジャンプする


    MOVF  RCREG,W
    MOVWF  INDF
    INCF  FSR,F
    DECFSZ COUNT_D,F
    GOTO  LPRCV
    MOVLW  0
    MOVWF  INDF

; ****** 受信データの格納 ******
;(24)RCREGレジスタから受信データを読み込む
;(25)バッファに格納
;(26)ポインタ +1
;(27)データカウンタ −1
;   LPRCV のラベルへ戻り繰り返す
;(28)25,24ビット目のDDS周波数データ(常に0)
;   バッファに格納

DDS
    MOVLW  0A0H
    MOVWF  FSR
    
MOVLW  9H
    MOVWF  COUNT_D

; ****** 格納データの取りだし ******
;(29)バッファの先頭アドレスをセットする
;   間接アドレスポインタをリセットする
;(30)9回繰り返す(DDS設定データ)
;   データカウンタのセット

DDS_SET
    MOVF  INDF,W
    MOVWF  TEMP
    MOVF  COUNT_D,W
    CALL  TABLE
    MOVWF  COUNT_S


;(31)バッファに格納されているデータをWregにロードする
;   一時保管データへ
;(32)データカウンタの値をWregへロードする(OFFSET)
;(33)シフトカウンタ値の読み込みサブルーチンへ
;(34)シフトカウンタのセット

DDS_LP
    RRF   TEMP,F
    BTFSS  STATUS,C
    GOTO  DATA_L
    GOTO  DATA_H


;(35)DDS設定データを取り出す。
;(36)データが1だったら次の命令をスキップ
;   DATA = [L]
;   DATA = [H]

SET_SCK
    BCF   PORTE,2
    NOP
    BSF   PORTE,2
    DECFSZ COUNT_S,F
    GOTO  DDS_LP
    INCF  FSR,F
    DECFSZ COUNT_D,F
    GOTO  DDS_SET

;(37)SCK = [L]
;(38)ポートの誤動作防止
;(39)SCK = [H]
;(40)シフトカウンタ −1
;   DDS_LP のラベルへ戻り繰り返す
;(41)間接アドレスポインタ +1
;(42)データカウンタ −1
;   DDS_SET のラベルへ戻り繰り返す

    BSF   PORTE,1
    NOP
    BCF   PORTE,0
    NOP
    BSF   PORTE,0

    GOTO  MAIN

;(43)DATA = [H]
;(44)ポートの誤動作防止
;(45)STB = [L]
;(46)ポートの誤動作防止
;(47)STB = [H]

;(48)繰り返しデータ受信動作に入る

DATA_L
    BCF   PORTE,1
    GOTO  SET_SCK
DATA_H
    BSF   PORTE,1
    GOTO  SET_SCK



;(49)DATA = [L]


;(50)DATA = [H]


;***********************************************************
; シフトカウンタ・テーブル
;***********************************************************
TABLE
    ADDWF  PCL,F
    NOP
    
DT    2,4,4,4,4,4,4,4,3
;(51)TABLEの定義(PC+OFFSET相当のシフトカウンタ値を持って戻る)
;   PC+OFFSET
;(52)ダミーデータ
;(53)各データに対するシフトカウンタ値
;***********************************************************
; RS232Cシリアル通信エラー時の処理
;***********************************************************
FRAME
    MOVLW  B'00001111'
    MOVWF  PORTB
    CALL  TIME1S
    MOVLW  B'00000000'
    MOVWF  PORTB
    MOVF  RCREG,W
    BTFSS  RCSTA,OERR
    GOTO  MAIN
; <フレーミングエラー時の処理>
;(54)00001111 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの点灯状態でエラーを知らせる)
;(55)1秒のウエイトを入れる
;(56)00000000 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの消灯)
;(57)ダミーの入力とFERRフラグをリセット(RCREGをリードするとクリア)
;(58)オーバーランエラーのチェック(1:エラー,0:正常)
;   オーバーランエラーがなければ MAIN のラベルへジャンプする

OVER
    MOVLW  B'11110000'
    MOVWF  PORTB
    CALL  TIME1S
    MOVLW  B'00000000'
    MOVWF  PORTB
    BCF   RCSTA,CREN
    BSF   RCSTA,CREN
    GOTO  MAIN


; <オーバーランエラー時の処理>
;(59)11110000 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの点灯状態でエラーを知らせる)
;(60)1秒のウエイトを入れる
;(61)00000000 を Wreg にロードする
;   PORTBへWregのデータを出力(LEDの消灯)
;(62)OERRのリセット(ビットCREN のクリアによりクリアする)
;(63)連続受信を許可する
;(64)MAIN のラベルへジャンプする

;***********************************************************
;遅延サブルーチン
;***********************************************************
;100μs遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・
;
;10ms遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・
;
;1s遅延サブルーチン(20MHzクロック時)
;・・・・・別記プログラムリスト参照・・・・・

    END
 

【プログラムの説明(3)】ここがポイント
ここでは、プログラムの説明(2)と変更のある部分(プログラム中で青字で記載)について解説を加えておきましょう。

(17)8回繰り返す(DDS設定データ),データカウンタのセット
パソコンから RS232C シリアル通信にて、次の1〜8までの各データが順に送られてくるので、受信動作を8回繰り返すようにデータカウンタをセットします。

  1. チップセレクトデータ
  2. コマンドデータ
  3. 周波数データ(0ビット目〜3ビット目)
  4. 周波数データ(4ビット目〜7ビット目)
  5. 周波数データ(8ビット目〜11ビット目)
  6. 周波数データ(12ビット目〜15ビット目)
  7. 周波数データ(16ビット目〜19ビット目)
  8. 周波数データ(20ビット目〜23ビット目)


(30)9回繰り返す(DDS設定データ),データカウンタのセット
(28)でバッファに書き込まれた周波数データ(24ビット目〜25ビット目)を含めて、1〜9までの9つのデータを取り出すため、動作を9回繰り返すようにデータカウンタをセットします。

(53)各データに対するシフトカウンタ値
表1に各DDS設定データに対するシフトカウンタ値を示します。
チップセレクトデータですが、チップセレクト端子は、CS2、CS1、CS0の3ビットで構成されています。
コマンドデータは、4ビットです。
次に周波数データですが、0ビット目〜23ビット目まで下位ビットから4ビット分で分割され、さらに、24,25ビット目で2ビット分というように、シフトカウンタ値を設定します。

表1.各DDS設定データに対するシフトカウンタ値
データの項目 シフトカウンタ値
チップセレクトデータ
コマンドデータ
周波数データ(0ビット目〜3ビット目)
周波数データ(4ビット目〜7ビット目)
周波数データ(8ビット目〜11ビット目)
周波数データ(12ビット目〜15ビット目)
周波数データ(16ビット目〜19ビット目)
周波数データ(20ビット目〜23ビット目)
周波数データ(24,25ビット目 ビットの値は常に0)



<項目>DDSの動作確認
それでは、パソコンからDDSをコントロールしてみましょう。
図3は、DDSコントロールプログラムソフトの周波数設定データを示しています。そのときのDDSの出力波形(図4)をオシロスコープで見たところです。3画像とも比較のため、タイムレンジは同じにしています。これらの結果から、DDSコントロールプログラムソフトを使って、パソコンからDDSを制御できることが確認できました。

(1)f=1MHz設定 (2)f=2MHz設定 (3)f=10MHz設定
図3.DDSコントロールプログラムを使ったDDSの設定
(1)f=1MHz設定 (2)f=2MHz設定 (3)f=10MHz設定
図4.DDSの出力波形




<前ページへ>
<TOPページへ>



楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル